package com.taomeishu.mailcrazy.tb.biz;

import java.util.List;
import java.util.Set;

import com.taobao.api.domain.Item;
import com.taobao.api.domain.ItemCat;
import com.taobao.api.domain.TradeRate;
import com.taobao.api.domain.User;
import com.taomeishu.mailcrazy.tb.bo.TbOpenBO;
import com.taomeishu.mailcrazy.tb.dal.ItemCatDAO;
import com.taomeishu.mailcrazy.tb.dal.LocationDAO;
import com.taomeishu.mailcrazy.tb.dal.TradeDAO;
import com.taomeishu.mailcrazy.tb.dal.UserDAO;
import com.taomeishu.mailcrazy.tb.domain.TbItemCatDO;
import com.taomeishu.mailcrazy.tb.domain.TbLocationDO;
import com.taomeishu.mailcrazy.tb.domain.TbSimpleTradeDO;
import com.taomeishu.mailcrazy.tb.domain.TbUserDO;
import com.taomeishu.mailcrazy.tb.query.ItemCatQuery;
import com.taomeishu.mailcrazy.tb.util.SearchResult;
import com.taomeishu.mailcrazy.tb.util.TbOpenUtil;
import com.taomeishu.mailcrazy.util.CollectionUtil;

public class TbFetcherAOImpl {

	private TbOpenBO tbOpenBO;
	
	private ItemCatDAO itemCatDAO;
	
	private UserDAO userDAO;
	
	private LocationDAO locationDAO;
	
	private TradeDAO tradeDAO;
	
	private int maxItemSearchPage = 3;
	
	private int tradeRatePageSize = 40;
	
	public void xx() {
		int page = 1;
		final int PAGE_SIZE = 100;
		ItemCatQuery itemCatQuery = new ItemCatQuery();
		itemCatQuery.setPageNo(page);
		itemCatQuery.setPageSize(100);
		List<TbItemCatDO> tbItemCatDOs = itemCatDAO.queryForPage(itemCatQuery);
		if (page == 1 && CollectionUtil.isEmpty(tbItemCatDOs)) {
			// 初始化cat
			fetchItemCats(0);
		}
		while (true) {
			itemCatQuery = new ItemCatQuery();
			itemCatQuery.setPageNo(page);
			itemCatQuery.setPageSize(PAGE_SIZE);
			tbItemCatDOs = itemCatDAO.queryForPage(itemCatQuery);
			proccessItemCats(tbItemCatDOs);
			if (CollectionUtil.isEmpty(tbItemCatDOs) || tbItemCatDOs.size() < PAGE_SIZE) {
				break;
			}
			++page;
		}
	}
	
	private void proccessItemCats(List<TbItemCatDO> tbItemCatDOs) {
		for (TbItemCatDO tbItemCatDO : tbItemCatDOs) {
			for (int i = 1; i <= maxItemSearchPage; ++i) {
				List<Item> items = tbOpenBO.searchItems(tbItemCatDO.getCid(), i);
				if (CollectionUtil.isEmpty(items)) {
					break;
				}
				proccessItems(items);
			}
		}
	}
	
	private void proccessItems(List<Item> items) {
		for (Item item : items) {
			String sellerNick = item.getNick();
			Long itemId = item.getNumIid();
			SearchResult<TradeRate> searchResult = tbOpenBO.searchTraderates(itemId, sellerNick, 1, tradeRatePageSize);
			long totalCount = searchResult.getResultCount();
			long pageCount = (totalCount + tradeRatePageSize - 1) /tradeRatePageSize;
			proccessTradeRate(searchResult.getResults(), item);
			for (int i = 2; i <= pageCount; ++i) {
				searchResult = tbOpenBO.searchTraderates(itemId, sellerNick, i, tradeRatePageSize);
				proccessTradeRate(searchResult.getResults(), item);
			}
		}
	}
	
	private void proccessTradeRate(List<TradeRate> tradeRates, Item item) {
		if (CollectionUtil.isEmpty(tradeRates)) {
			return;
		}
		Set<String> nicks = CollectionUtil.newHashSet();
		for (TradeRate tradeRate : tradeRates) {
			String nick = tradeRate.getNick();
			String ratedNick = tradeRate.getRatedNick();
			nicks.add(nick);
			nicks.add(ratedNick);
			
			proccessTrades(tradeRate, item);
		}
		proccessUser(nicks);
		
	}
	
	private void proccessTrades(TradeRate tradeRate, Item item) {
		TbSimpleTradeDO tbTradeDO = TbOpenUtil.toTbTradeDO(tradeRate, item);
		tradeDAO.insertOrUpdateTrade(tbTradeDO);
	}
	
	private void proccessUser(Set<String> nicks) {
		List<User> users = tbOpenBO.getPublicUsers(nicks);
		if (CollectionUtil.isEmpty(users)) {
			return;
		}
		updateUsers(users);
	}
	
	private void updateUsers(List<User> users) {
		for (User user : users) {
			TbUserDO tbUserDO = TbOpenUtil.toTbUserDO(user);
			userDAO.insertOrUpdateUser(tbUserDO);
			List<TbLocationDO> locations = TbOpenUtil.getTbLocations(user);
			for (TbLocationDO locationDO : locations) {
				locationDAO.saveOrUpdateTbLocationDO(locationDO);
			}
			
		}
	}
	
	public void fetchItemCats() {
		fetchItemCats(0L);
	}
	
	private void fetchItemCats(long parentCid) {
		List<ItemCat> itemCats = tbOpenBO.getItemCatByParentCid(parentCid);
		if (CollectionUtil.isEmpty(itemCats)) {
			return;
		}
		for (ItemCat itemCat : itemCats) {
			TbItemCatDO tbItemCatDO = TbOpenUtil.toTbItemCatDO(itemCat);
			itemCatDAO.insertOrUpdateByCid(tbItemCatDO);
			if (itemCat.getIsParent()) {
				fetchItemCats(itemCat.getCid());
			}
		}
	}

	public void setTbOpenBO(TbOpenBO tbOpenBO) {
		this.tbOpenBO = tbOpenBO;
	}

	public void setItemCatDAO(ItemCatDAO itemCatDAO) {
		this.itemCatDAO = itemCatDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public void setLocationDAO(LocationDAO locationDAO) {
		this.locationDAO = locationDAO;
	}

	public void setTradeDAO(TradeDAO tradeDAO) {
		this.tradeDAO = tradeDAO;
	}
	
}
